package com.imdroid.lite.services;

import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.apache.http.message.BasicNameValuePair;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.imdroid.lite.IMDroid;
import com.imdroid.lite.model.TeamTalk;
import com.imdroid.lite.net.HttpHelper;

public class NotificationService extends Service {
	private String TAG = "NotificationService";
	/**
	 * Connect to server
	 */
	public static final int CONNECTED = 9001;
	/**
	 * Connect from the fail
	 */
	public static final int CONNECT_FAIL = 9002;
	/**
	 * receive the message֪
	 */
	public static final int RECEIVED = 9003;
	/**
	 * disconnect to the server
	 */
	public static final int DISCONNECTED = 9004;
	/**
	 * if it is the connect
	 */
	private static boolean connected = false;
	/**
	 * the last active time
	 */
	private static long lastActive;
	/**
	 * the heart beat inverval
	 */
	private final static int HEAT_BEAT_INTERVAL = 5 * 60 * 1000;

	/**
	 * The mssage handler
	 */
	private static NotificationHandler eventHandler = new NotificationHandler();

	/**
	 * is it is the services is running
	 */
	private static boolean running;
	/**
	 * The http connection
	 */
	private static HttpURLConnection httpConnection = null;
	/**
	 * The connection input stream
	 */
	private static DataInputStream inputStream = null;
	/**
	 * The thread of the notficuation
	 */
	private Thread notificationThread;

	/**
	 * Get the notification handler
	 */
	public static NotificationHandler getNotificationHandler() {
		return eventHandler;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Service#onBind(android.content.Intent)
	 */
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "on Bind...");
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Service#onDestroy()
	 */
	public void onDestroy() {
		Log.d(TAG, "on destory...");
		new Thread() {
			public void run() {
				try {
					// 从服务器上断开连接
					disconnect();
				} catch (Exception e) {
					e.printStackTrace();
				}

			}
		}.start();

		running = false;
		notificationThread.interrupt();
		notificationThread = null;
		super.onDestroy();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Service#onStartCommand(android.content.Intent, int, int)
	 */
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		Log.d(this.getClass().getSimpleName(), "onStartCommand..."
				+ notificationThread);
		running = true;
		if (notificationThread == null) {
			connected = false;
			notificationThread = new Thread(new NotificationReceiver());
			notificationThread.start();
		}

		return START_STICKY;
	}

	/**
	 * Check if the connection is alive
	 * 
	 * @return if the connection is alive
	 */
	public static boolean isLive() {
		return (lastActive == 0 || (System.currentTimeMillis() - lastActive < HEAT_BEAT_INTERVAL * 1.2));
	}

	/**
	 * connect to the server
	 * 
	 * @throws IOException
	 * @throws MalformedURLException
	 */
	private void connect() throws MalformedURLException, IOException {
		Log.d(TAG, "Connecting ... ");

		httpConnection = (HttpURLConnection) new URL(HttpHelper.ServerAddress
				+ "/i/Connect?userId=" + IMDroid.getUser().getUser_id())
				.openConnection();
		httpConnection.setDoInput(true);
		inputStream = new DataInputStream(httpConnection.getInputStream());
		eventHandler.obtainMessage(CONNECTED).sendToTarget();
		System.out.println("Connected ... ");
		connected = true;

		// httpConnection = (HttpURLConnection) new URL(HttpHelper.ServerAddress
		// + "i/Connect?userId=" + IMDroid.getUser().getUser_id())
		// .openConnection();
		// httpConnection.setDoInput(true);
		// //httpConnection.setRequestMethod("GET");
		// //httpConnection.connect();
		// inputStream = new DataInputStream(httpConnection.getInputStream());
		// Log.d(TAG, "Connected ... ");
		// eventHandler.obtainMessage(CONNECTED).sendToTarget();
		// connected = true;
	}

	/**
	 * Disconnect from the server
	 * 
	 * @throws Exception
	 * 
	 * @throws IOException
	 * @throws MalformedURLException
	 */
	private void disconnect() throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("userId", IMDroid.getUser()
				.getUser_id() + ""));
		HttpHelper.execute("/i/Disconnect", params);
	}

	/**
	 * The receive of notification
	 * 
	 */
	private class NotificationReceiver implements Runnable {

		/*
		 * (non-Javadoc)
		 * 
		 * @see java.lang.Runnable#run()
		 */
		public void run() {
			// 线程循环
			while (running) {
				try {
					// 如果没有连接则连接
					if (!connected)
						connect();
					// 如果连接不成功，则抛错，准备重连接
					if (!connected)
						throw new Exception("Not connected");

					// 接受到数据
					int messageType = inputStream.readInt();
					Log.d(TAG, "Message Type: " + messageType);
					lastActive = System.currentTimeMillis();
					// 非语音信息
					if (messageType == 1) {
						String message = inputStream.readUTF().trim();
						Log.d(TAG, "Message Content: " + message);
						

						if (message != null && message.length() == 0)
							continue;

						// 接受到错误数据
						if (message == null || message.length() <= 0)
							throw new RuntimeException("Empty message received");

						eventHandler.obtainMessage(RECEIVED, message)
								.sendToTarget();
					} else if (messageType == 2) {
						// 语音信息
						int memberId = inputStream.readInt();
						String memberNickName = inputStream.readUTF();
						String fileName = inputStream.readUTF();
						FileOutputStream fos = new FileOutputStream(
								IMDroid.TEMP_FOLDER + fileName);
						long fileLength = inputStream.readLong();

						Log.d(TAG, "Message Voice - Id: " + memberId
								+ " nickName:" + memberNickName + " fileName:"
								+ fileName + " length:" + fileLength);

						int len = 0;
						long totalLength = 0;
						byte[] buffer = new byte[1024 * 50];

						while ((len = inputStream.read(buffer)) != -1) {
							Log.d(TAG, "Message Voice - Loading " + len
									+ " byte");
							fos.write(buffer, 0, len);
							fos.flush();
							totalLength += len;
							if (totalLength >= fileLength)
								break;
						}
						fos.close();
						Log.d(TAG, "Message Voice - Load Done!");
						
						TeamTalk tt = new TeamTalk();
						tt.setFile(IMDroid.TEMP_FOLDER + fileName);
						tt.setFileNameInServer(fileName);
						tt.setMemberId(memberId);
						tt.setMemberName(memberNickName);

						eventHandler.obtainMessage(RECEIVED, tt).sendToTarget();
					}

				} catch (Exception e) {
					connected = false;
					// 打印错误
					e.printStackTrace();
					eventHandler.obtainMessage(DISCONNECTED, e.getMessage())
							.sendToTarget();
					// 断开连接
					try {
						if (inputStream != null)
							inputStream.close();

						if (httpConnection != null)
							httpConnection.disconnect();
					} catch (Exception ex) {
						ex.printStackTrace();
					}
					// 延时重连接
					try {
						Thread.sleep(1 * 1000);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
				}
			}
			System.out.println("Thread finish");
		}

	}
}
